﻿
//------------------------------------------------------------
// shaco Framework
// Copyright © 2017-2021 chang.liu All rights reserved.
// Feedback: 449612236@qq.com
//------------------------------------------------------------

using shaco.Base;
using UnityEngine;

namespace shaco
{
    public class DefaultResources : IResources
    {
        public string currentPackageName => "<Default>";

        public bool Exists(string path)
        {
            return null != Resources.Load(path);
        }

        public bool Exists(IResourceHandleBase handle)
        {
            if (handle is DefaultResourcesHandle)
                return Exists((handle as DefaultResourcesHandle).assetPath);
            else if (handle is DefaultAllResourcesHandle)
                return Exists((handle as DefaultAllResourcesHandle).assetPath);
            else
                throw new System.NotImplementedException("DefaultResources Exists error: unsupport type=" + handle?.GetType());
        }

        public IResourceHandle Load<T>(string path) where T : UnityEngine.Object
        {
            var handle = new DefaultResourcesHandle();
            handle.Load<T>(path);
            return handle;
        }

        public IResourceHandle Load(string path, System.Type type)
        {
            var handle = new DefaultResourcesHandle();
            handle.Load<Object>(path);
            return handle;
        }

        public IResourceHandle LoadAsync<T>(string path) where T : Object
        {
            var handle = new DefaultResourcesHandle();
            handle.Load<Object>(path);
            return handle;
        }

        public IAllResourceHandle LoadAll<T>(string path) where T : UnityEngine.Object
        {
            var handle = new DefaultAllResourcesHandle();
            handle.LoadAll<Object>(path);
            return handle;
        }

        public IAllResourceHandle LoadAllAsync<T>(string path) where T : UnityEngine.Object
        {
            var handle = new DefaultAllResourcesHandle();
            handle.LoadAll<Object>(path);
            return handle;
        }

        public void Release(IResourceHandleBase handle)
        {
            TryUnloadUnusedAsset(handle);
        }

        public void SetCurrentPackageName(string packageName)
        {
            //do nothing
        }

        public System.Collections.IEnumerator UnloadUnusedAssetsAsync()
        {
            Resources.UnloadUnusedAssets();
            return null;
        }

        public void TryUnloadUnusedAsset(IResourceHandleBase handle)
        {
            if (handle is DefaultResourcesHandle)
            {
                var obj = (handle as DefaultResourcesHandle).assetObject as UnityEngine.Object;
                if (null != obj)
                    Resources.UnloadAsset(obj);
                else
                    Log.Warning("DefaultResources TryUnloadUnusedAsset warning: not UnityEngine.Object, obj=" + obj);
            }
            else if (handle is DefaultAllResourcesHandle)
            {
                var objs = (handle as DefaultAllResourcesHandle).assetObjects;
                foreach (var iter in objs)
                {
                    var obj = iter as UnityEngine.Object;
                    if (null != obj)
                        Resources.UnloadAsset(obj);
                    else
                        Log.Warning("DefaultResources TryUnloadUnusedAsset warning: not all UnityEngine.Object, obj=" + obj);
                }
            }
            else
                throw new System.NotImplementedException("DefaultResources Exists error: unsupport type=" + handle?.GetType());
        }
    }

#if UNITY_EDITOR
    public class DefaultEdtiorResourcesHandle<T> : IResourceHandle where T : UnityEngine.Object
    {
        public object assetObject => _assetObject;
        T _assetObject;
        public float progress => 1.0f;
        public bool isDone => true;
        public object Current => this;

        public DefaultEdtiorResourcesHandle(string path)
        {
            _assetObject = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
        }

        public bool MoveNext()
        {
            return false;
        }

        public void OnCompleted(System.Action<IResourceHandleBase> callback)
        {
            callback(this);
        }

        public void Reset()
        {
        }
        
        public void Release()
        {
            
        }
    }
#endif
}
